package com.example.a1.fannong.core.http;

import com.example.a1.fannong.core.app.MyApplication;

import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 下载任务
 *
 * @author nishuhang 2017年07月05日
 */
public class FileDownloader implements Runnable {
    public static final Object lock = new Object();
    private String filePath;
    private String url;
    private DownloadListener downloadListener;

    public FileDownloader(String filePath, String url, DownloadListener downloadListener) {
        super();
        this.filePath = filePath;
        this.url = url;
        this.downloadListener = downloadListener;
    }

    private static void closeQuietly(Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
        }
    }


    @Override
    public void run() {
        File file = new File(filePath + ".tmp");

        DownloadResult downloadResult = DownloadResult.FAILED;
        if (file.exists()) {
            file.delete();
        }

        OutputStream outputStream = null;
        HttpURLConnection httpURLConnection = null;
        try {
            httpURLConnection = (HttpURLConnection) new URL(url).openConnection();
            httpURLConnection.setConnectTimeout(5000);
            httpURLConnection.setReadTimeout(5000);
            httpURLConnection.setRequestMethod("GET");
            int responseCode = httpURLConnection.getResponseCode();
            if (responseCode == 200) {
                InputStream inputStream = httpURLConnection.getInputStream();
                synchronized (lock) {
                    file.getParentFile().mkdirs();
                    file.createNewFile();
                }
                outputStream = new FileOutputStream(file);

                byte[] buffer = new byte[1024];
                int length = -1;
                int totalSize = httpURLConnection.getContentLength();
                int currentSize = 0;
                long lastNotify = System.currentTimeMillis();
                while ((length = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, length);
                    currentSize += length;
                    if ((System.currentTimeMillis() - lastNotify) > 200) {
                        lastNotify = System.currentTimeMillis();
                        onProgressChange(totalSize, currentSize);
                    }
                }
                outputStream.flush();
                onProgressChange(currentSize, currentSize);

                file.renameTo(new File(filePath));

                downloadResult = DownloadResult.SUCCESSFUL;
            } else {
                file.deleteOnExit();
            }
        } catch (IOException e) {
            e.printStackTrace();
            if (outputStream != null)
                try {
                    outputStream.flush();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            file.delete();
        } finally {
            closeQuietly(outputStream);
            if (httpURLConnection != null)
                httpURLConnection.disconnect();
        }
        onDownloadFinish(downloadResult);
    }

    private void onProgressChange(final int totalSize, final int currentSize) {
        MyApplication.getInstance().getHandler().post(new Runnable() {
            @Override
            public void run() {
                if (downloadListener != null) {
                    downloadListener.onProgressChange(filePath, totalSize, currentSize);
                }
            }
        });
    }

    /**
     * 下载结果回调
     */
    private void onDownloadFinish(final DownloadResult downloadResult) {
        MyApplication.getInstance().getHandler().post(new Runnable() {
            @Override
            public void run() {
                if (downloadListener != null) {
                    downloadListener.onDownloadFinish(filePath, downloadResult);
                }
            }
        });
    }

    /** 下载结果 */
    public enum DownloadResult {
        /** */
        SUCCESSFUL,

        /** 下载失败 */
        FAILED,
    }

    public interface DownloadListener {
        /**
         * 进度回调
         *
         * @param totalSize   总的直接数，如果服务器没有返回该值，为-1
         * @param currentSize 当前已经下载的字节数
         */
        void onProgressChange(String filePath, int totalSize, int currentSize);

        /**
         * 下载结果回调
         */
        void onDownloadFinish(String filePath, DownloadResult downloadResult);
    }
}
